{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<h1>Python入门(上)</h1>\n",
    "\n",
    "1. [简介](#简介)\n",
    "\n",
    "2. [变量、运算符与数据类型](#变量、运算符与数据类型)<br>\n",
    "   [1. 注释](#1.-注释)<br>\n",
    "   [2. 运算符](#2.-运算符)<br>\n",
    "   [3. 变量和赋值](#3.-变量和赋值)<br>\n",
    "   [4. 数据类型与转换](#4.-数据类型与转换)<br>\n",
    "   [5. print()函数](#5.-print()-函数)<br>\n",
    " \n",
    "3. [位运算](#位运算)<br>\n",
    "   [1. 原码、反码和补码](#1.-原码、反码和补码)<br>\n",
    "   [2. 按位运算](#2.-按位运算)<br>\n",
    "   [3. 利用位运算实现快速计算](#3.-利用位运算实现快速计算)<br>\n",
    "   [4. 利用位运算实现整数集合](#4.-利用位运算实现整数集合)<br>\n",
    "   \n",
    "4. [条件语句](#条件语句)<br>\n",
    "   [1. if 语句](#1.-if-语句)<br>\n",
    "   [2. if - else 语句](#2.-if---else-语句)<br>\n",
    "   [3. if - elif - else 语句](#3.-if---elif---else-语句)<br>\n",
    "   [4. assert 关键词](#4.-assert-关键词)<br>\n",
    "   \n",
    "5. [循环语句](#循环语句)<br>\n",
    "   [1. while 循环](#1.-while-循环)<br>\n",
    "   [2. while - else 循环](#2.-while---else-循环)<br>\n",
    "   [3. for 循环](#3.-for-循环)<br>\n",
    "   [4. for - else 循环](#4.-for---else-循环)<br>\n",
    "   [5. range() 函数](#5.-range()-函数)<br>\n",
    "   [6. enumerate()函数](#6.-enumerate()函数)<br>\n",
    "   [7. break 语句](#7.-break-语句)<br>\n",
    "   [8. continue 语句](#8.-continue-语句)<br>\n",
    "   [9. pass 语句](#9.-pass-语句)<br>\n",
    "   [10. 推导式](#10.-推导式)<br>\n",
    "   \n",
    "6. [异常处理](#异常处理)<br>\n",
    "   [1. Python 标准异常总结](#1.-Python-标准异常总结)<br>\n",
    "   [2. Python 标准警告总结](#2.-Python标准警告总结)<br>\n",
    "   [3. try - except 语句](#3.-try---except-语句)<br>\n",
    "   [4. try - except - finally 语句](#4.-try---except---finally-语句)<br>\n",
    "   [5. try - except - else 语句](#5.-try---except---else-语句)<br>\n",
    "   [6. raise语句](#6.-raise语句)<br>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 简介\n",
    "\n",
    "Python 是一种通用编程语言，其在科学计算和机器学习领域具有广泛的应用。如果我们打算利用 Python 来执行机器学习，那么对 Python 有一些基本的了解就是至关重要的。本 Python 入门系列体验就是为这样的初学者精心准备的。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "本实验包括以下内容：\n",
    "- 变量、运算符与数据类型\n",
    "    - 注释\n",
    "    - 运算符\n",
    "    - 变量和赋值\n",
    "    - 数据类型与转换\n",
    "    - print() 函数\n",
    "- 位运算\n",
    "    - 原码、反码和补码\n",
    "    - 按位非操作 ~\n",
    "    - 按位与操作 &\n",
    "    - 按位或操作 |\n",
    "    - 按位异或操作 ^\n",
    "    - 按位左移操作 <<\n",
    "    - 按位右移操作 >>\n",
    "    - 利用位运算实现快速计算\n",
    "    - 利用位运算实现整数集合\n",
    "- 条件语句\n",
    "    - if 语句\n",
    "    - if - else 语句\n",
    "    - if - elif - else 语句\n",
    "    - assert 关键词\n",
    "- 循环语句\n",
    "    - while 循环\n",
    "    - while - else 循环\n",
    "    - for 循环\n",
    "    - for - else 循环\n",
    "    - range() 函数\n",
    "    - enumerate()函数\n",
    "    - break 语句\n",
    "    - continue 语句\n",
    "    - pass 语句\n",
    "    - 推导式\n",
    "- 异常处理\n",
    "    - Python 标准异常总结\n",
    "    - Python 标准警告总结\n",
    "    - try - except 语句\n",
    "    - try - except - finally 语句\n",
    "    - try - except - else 语句\n",
    "    - raise语句\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 变量、运算符与数据类型\n",
    "\n",
    "## 1. 注释\n",
    "- 在 Python 中，`#` 表示注释，作用于整行。\n",
    "\n",
    "【例子】单行注释"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Hello world\n"
     ]
    }
   ],
   "source": [
    "# 这是一个注释\n",
    "print(\"Hello world\")\n",
    "\n",
    "# Hello world"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "- `''' '''` 或者 `\"\"\" \"\"\"` 表示区间注释，在三引号之间的所有内容被注释\n",
    "\n",
    "【例子】多行注释"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Hello china\n",
      "hello china\n"
     ]
    }
   ],
   "source": [
    "'''\n",
    "这是多行注释，用三个单引号\n",
    "这是多行注释，用三个单引号\n",
    "这是多行注释，用三个单引号\n",
    "'''\n",
    "print(\"Hello china\") \n",
    "# Hello china\n",
    "\n",
    "\"\"\"\n",
    "这是多行注释，用三个双引号\n",
    "这是多行注释，用三个双引号 \n",
    "这是多行注释，用三个双引号\n",
    "\"\"\"\n",
    "print(\"hello china\") \n",
    "# hello china"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "【我是测试题1】请在下方代码块中打印(print)出 hello+你的姓名\n",
    "<br>如：print(\"hello 老表\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 写下你的答案\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "\n",
    "\n",
    "\n",
    "## 2. 运算符\n",
    "\n",
    "\n",
    "\n",
    "<b>算术运算符</b>\n",
    "\n",
    "操作符 | 名称 | 示例\n",
    ":---:|:---:|:---:\n",
    "`+` | 加 | `1 + 1`\n",
    "`-` | 减 | `2 - 1`\n",
    "`*` | 乘 | `3 * 4`\n",
    "`/` | 除 | `3 / 4`\n",
    "`//`| 整除（地板除）| `3 // 4`\n",
    "`%` | 取余| `3 % 4`\n",
    "`**`| 幂 | `2 ** 3`\n",
    "\n",
    "【例子】"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "2\n",
      "1\n",
      "12\n",
      "0.75\n",
      "0\n",
      "3\n",
      "8\n"
     ]
    }
   ],
   "source": [
    "print(1 + 1)  # 2\n",
    "print(2 - 1)  # 1\n",
    "print(3 * 4)  # 12\n",
    "print(3 / 4)  # 0.75\n",
    "print(3 // 4)  # 0\n",
    "print(3 % 4)  # 3\n",
    "print(2 ** 3)  # 8"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "\n",
    "<b>比较运算符</b>\n",
    "\n",
    "操作符 | 名称 | 示例\n",
    ":---:|:---:|:---:\n",
    "`>` |大于| `2 > 1`\n",
    "`>=`|大于等于| `2 >= 4`\n",
    "`<` |小于| `1 < 2`\n",
    "`<=`|小于等于| `5 <= 2`\n",
    "`==`|等于| `3 == 4`\n",
    "`!=`|不等于| `3 != 5`\n",
    "\n",
    "【例子】"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "True\n",
      "False\n",
      "True\n",
      "False\n",
      "False\n",
      "True\n"
     ]
    }
   ],
   "source": [
    "print(2 > 1)  # True\n",
    "print(2 >= 4)  # False\n",
    "print(1 < 2)  # True\n",
    "print(5 <= 2)  # False\n",
    "print(3 == 4)  # False\n",
    "print(3 != 5)  # True"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "<b>逻辑运算符</b>\n",
    "\n",
    "操作符 | 名称 | 示例\n",
    ":---:|:---:|:---:\n",
    "`and`|与| `(3 > 2) and (3 < 5)`\n",
    "`or` |或| `(1 > 3) or (9 < 2)`\n",
    "`not`|非| `not (2 > 1)`\n",
    "\n",
    "【例子】"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "True\n",
      "False\n",
      "False\n"
     ]
    }
   ],
   "source": [
    "print((3 > 2) and (3 < 5))  # True\n",
    "print((1 > 3) or (9 < 2))  # False\n",
    "print(not (2 > 1))  # False"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "<b>位运算符</b>\n",
    "\n",
    "操作符 | 名称 | 示例\n",
    ":---:|:---:|:---:\n",
    "`~` |按位取反|`~4`\n",
    "`&` |按位与  |`4 & 5`\n",
    "`|` |按位或  |`4 | 5`\n",
    "`^` |按位异或|`4 ^ 5`\n",
    "`<<`|左移    |`4 << 2`\n",
    "`>>`|右移    |`4 >> 2`\n",
    "\n",
    "【例子】有关二进制的运算，参见“位运算”部分的讲解。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0b100\n",
      "0b101\n",
      "-0b101 -5\n",
      "0b100 4\n",
      "0b101 5\n",
      "0b1 1\n",
      "0b10000 16\n",
      "0b1 1\n"
     ]
    }
   ],
   "source": [
    "print(bin(4))  # 0b100\n",
    "print(bin(5))  # 0b101\n",
    "print(bin(~4), ~4)  # -0b101 -5\n",
    "print(bin(4 & 5), 4 & 5)  # 0b100 4\n",
    "print(bin(4 | 5), 4 | 5)  # 0b101 5\n",
    "print(bin(4 ^ 5), 4 ^ 5)  # 0b1 1\n",
    "print(bin(4 << 2), 4 << 2)  # 0b10000 16\n",
    "print(bin(4 >> 2), 4 >> 2)  # 0b1 1"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "\n",
    "<b>三元运算符</b>\n",
    "\n",
    "【例子】"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "4\n"
     ]
    }
   ],
   "source": [
    "x, y = 4, 5\n",
    "if x < y:\n",
    "    small = x\n",
    "else:\n",
    "    small = y\n",
    "\n",
    "print(small)  # 4"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "有了这个三元操作符的条件表达式，你可以使用一条语句来完成以上的条件判断和赋值操作。\n",
    "\n",
    "【例子】"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "4\n"
     ]
    }
   ],
   "source": [
    "x, y = 4, 5\n",
    "small = x if x < y else y\n",
    "print(small)  # 4"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "<b>其他运算符</b>\n",
    "\n",
    "操作符 | 名称 | 示例\n",
    ":---:|:---:|:---:\n",
    "`in`|存在| `'A' in ['A', 'B', 'C']`\n",
    "`not in`|不存在|`'h' not in ['A', 'B', 'C']`\n",
    "`is`|是| `\"hello\" is \"hello\"`\n",
    "`not is`|不是|`\"hello\" is not \"hello\"`\n",
    "\n",
    "\n",
    "【例子】"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "A exists\n",
      "h not exists\n"
     ]
    }
   ],
   "source": [
    "letters = ['A', 'B', 'C']\n",
    "if 'A' in letters:\n",
    "    print('A' + ' exists')\n",
    "if 'h' not in letters:\n",
    "    print('h' + ' not exists')\n",
    "\n",
    "# A exists\n",
    "# h not exists"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "【例子】比较的两个变量均指向不可变类型。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "True True\n",
      "False False\n"
     ]
    }
   ],
   "source": [
    "a = \"hello\"\n",
    "b = \"hello\"\n",
    "print(a is b, a == b)  # True True\n",
    "print(a is not b, a != b)  # False False"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "【例子】比较的两个变量均指向可变类型。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "False True\n",
      "True False\n"
     ]
    }
   ],
   "source": [
    "a = [\"hello\"]\n",
    "b = [\"hello\"]\n",
    "print(a is b, a == b)  # False True\n",
    "print(a is not b, a != b)  # True False"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "注意：\n",
    "- is, is not 对比的是两个变量的内存地址\n",
    "- ==, != 对比的是两个变量的值\n",
    "- 比较的两个变量，指向的都是地址不可变的类型（str等），那么is，is not 和 ==，！= 是完全等价的。\n",
    "- 对比的两个变量，指向的是地址可变的类型（list，dict，tuple等），则两者是有区别的。\n",
    "\n",
    "\n",
    "<b>运算符的优先级</b>\n",
    "\n",
    "| 运算符 | 描述 |\n",
    "|-----|-----|\n",
    "| ** | 指数（最高优先级）   |\n",
    "| ~+- | 按位翻转，一元加号和减号 |\n",
    "| * / % // | 乘，除，取模和取整除）   |\n",
    "| + - | 加法减法 |\n",
    "| >> << | 右移，左移运算符 |\n",
    "|&| 位‘AND’|\n",
    "| ^\\| | 位运算符  |\n",
    "| <=<>>=| 比较运算符 |\n",
    "| <>==!= | 等于运算符  |\n",
    "| =%=/=//=-=+=*=**= | 赋值运算符 |\n",
    "| is is not | 身份运算符   |\n",
    "| in not in | 成员运算符 |\n",
    "| not and or | 逻辑运算符   |\n",
    "\n",
    "【例子】"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "-9\n",
      "0.1111111111111111\n",
      "0\n",
      "-12.5\n",
      "True\n"
     ]
    }
   ],
   "source": [
    "print(-3 ** 2)  # -9\n",
    "print(3 ** -2)  # 0.1111111111111111\n",
    "print(1 << 3 + 2 & 7)  # 0\n",
    "print(-3 * 2 + 5 / -2 - 4)  # -12.5\n",
    "print(3 < 4 and 4 < 5)  # True"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "【我是测试题2】下面这段代码的运行结果是什么？"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 运行一下结果就出来了\n",
    "a = \"hello\"\n",
    "b = \"hello\"\n",
    "print(a is b, a == b)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "\n",
    "## 3. 变量和赋值\n",
    "\n",
    "- 在使用变量之前，需要对其先赋值。\n",
    "- 变量名可以包括字母、数字、下划线、但变量名不能以数字开头。\n",
    "- Python 变量名是大小写敏感的，foo != Foo。\n",
    "\n",
    "【例子】"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "老马的程序人生\n"
     ]
    }
   ],
   "source": [
    "teacher = \"老马的程序人生\"\n",
    "print(teacher)  # 老马的程序人生"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "【例子】"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "5\n"
     ]
    }
   ],
   "source": [
    "first = 2\n",
    "second = 3\n",
    "third = first + second\n",
    "print(third)  # 5"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "【例子】"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "老马的程序人生,小马的程序人生\n"
     ]
    }
   ],
   "source": [
    "myTeacher = \"老马的程序人生\"\n",
    "yourTeacher = \"小马的程序人生\"\n",
    "ourTeacher = myTeacher + ',' + yourTeacher\n",
    "print(ourTeacher)  # 老马的程序人生,小马的程序人生"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "【我是测试题3】运行下面一段代码看看结果是什么？"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "output_type": "stream",
     "name": "stdout",
     "text": [
      "学习\n"
     ]
    }
   ],
   "source": [
    "# 运行一下就好啦\n",
    "set_1 = {\"欢迎\", \"学习\",\"Python\"}\n",
    "print(set_1.pop())"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "\n",
    "\n",
    "\n",
    "## 4. 数据类型与转换\n",
    "\n",
    "\n",
    "类型 | 名称 | 示例\n",
    ":---:|:---:|:---:\n",
    "int | 整型 `<class 'int'>`| `-876, 10`\n",
    "float | 浮点型`<class 'float'>`| `3.149, 11.11`\n",
    "bool | 布尔型`<class 'bool'>` | `True, False`\n",
    "\n",
    "<b>整型</b>\n",
    "\n",
    "【例子】通过 `print()` 可看出 `a` 的值，以及类 (class) 是`int`。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1031 <class 'int'>\n"
     ]
    }
   ],
   "source": [
    "a = 1031\n",
    "print(a, type(a))\n",
    "# 1031 <class 'int'>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "Python 里面万物皆对象（object），整型也不例外，只要是对象，就有相应的属性 （attributes） 和方法（methods）。\n",
    "\n",
    "【例子】"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "['__abs__', '__add__', '__and__', '__bool__', '__ceil__', '__class__', '__delattr__', '__dir__', '__divmod__', '__doc__', '__eq__', '__float__', '__floor__', '__floordiv__', '__format__', '__ge__', '__getattribute__', '__getnewargs__', '__gt__', '__hash__', '__index__', '__init__', '__init_subclass__', '__int__', '__invert__', '__le__', '__lshift__', '__lt__', '__mod__', '__mul__', '__ne__', '__neg__', '__new__', '__or__', '__pos__', '__pow__', '__radd__', '__rand__', '__rdivmod__', '__reduce__', '__reduce_ex__', '__repr__', '__rfloordiv__', '__rlshift__', '__rmod__', '__rmul__', '__ror__', '__round__', '__rpow__', '__rrshift__', '__rshift__', '__rsub__', '__rtruediv__', '__rxor__', '__setattr__', '__sizeof__', '__str__', '__sub__', '__subclasshook__', '__truediv__', '__trunc__', '__xor__', 'bit_length', 'conjugate', 'denominator', 'from_bytes', 'imag', 'numerator', 'real', 'to_bytes']\n"
     ]
    }
   ],
   "source": [
    "b = dir(int)\n",
    "print(b)\n",
    "\n",
    "# ['__abs__', '__add__', '__and__', '__bool__', '__ceil__', '__class__',\n",
    "# '__delattr__', '__dir__', '__divmod__', '__doc__', '__eq__',\n",
    "# '__float__', '__floor__', '__floordiv__', '__format__', '__ge__',\n",
    "# '__getattribute__', '__getnewargs__', '__gt__', '__hash__',\n",
    "# '__index__', '__init__', '__init_subclass__', '__int__', '__invert__',\n",
    "# '__le__', '__lshift__', '__lt__', '__mod__', '__mul__', '__ne__',\n",
    "# '__neg__', '__new__', '__or__', '__pos__', '__pow__', '__radd__',\n",
    "# '__rand__', '__rdivmod__', '__reduce__', '__reduce_ex__', '__repr__',\n",
    "# '__rfloordiv__', '__rlshift__', '__rmod__', '__rmul__', '__ror__',\n",
    "# '__round__', '__rpow__', '__rrshift__', '__rshift__', '__rsub__',\n",
    "# '__rtruediv__', '__rxor__', '__setattr__', '__sizeof__', '__str__',\n",
    "# '__sub__', '__subclasshook__', '__truediv__', '__trunc__', '__xor__',\n",
    "# 'bit_length', 'conjugate', 'denominator', 'from_bytes', 'imag',\n",
    "# 'numerator', 'real', 'to_bytes']"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "对它们有个大概印象就可以了，具体怎么用，需要哪些参数 （argument），还需要查文档。看个`bit_length()`的例子。\n",
    "\n",
    "【例子】找到一个整数的二进制表示，再返回其长度。\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0b10000000111\n",
      "11\n"
     ]
    }
   ],
   "source": [
    "a = 1031\n",
    "print(bin(a))  # 0b10000000111\n",
    "print(a.bit_length())  # 11"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "\n",
    "<b>浮点型</b>\n",
    "\n",
    "【例子】"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1 <class 'int'>\n",
      "1.0 <class 'float'>\n",
      "2.3e-07\n",
      "2.3e-07\n"
     ]
    }
   ],
   "source": [
    "print(1, type(1))\n",
    "# 1 <class 'int'>\n",
    "\n",
    "print(1., type(1.))\n",
    "# 1.0 <class 'float'>\n",
    "\n",
    "a = 0.00000023\n",
    "b = 2.3e-7\n",
    "print(a)  # 2.3e-07\n",
    "print(b)  # 2.3e-07"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "有时候我们想保留浮点型的小数点后 `n` 位。可以用 `decimal` 包里的 `Decimal` 对象和 `getcontext()` 方法来实现。\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "import decimal\n",
    "from decimal import Decimal"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "Python 里面有很多用途广泛的包 (package)，用什么你就引进 (import) 什么。包也是对象，也可以用上面提到的`dir(decimal)` 来看其属性和方法。\n",
    "\n",
    "【例子】`getcontext()` 显示了 `Decimal` 对象的默认精度值是 28 位 (`prec=28`)。\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "output_type": "stream",
     "name": "stdout",
     "text": [
      "Context(prec=28, rounding=ROUND_HALF_EVEN, Emin=-999999, Emax=999999, capitals=1, clamp=0, flags=[Inexact, Rounded], traps=[InvalidOperation, DivisionByZero, Overflow])\n"
     ]
    }
   ],
   "source": [
    "a = decimal.getcontext()\n",
    "print(a)\n",
    "\n",
    "# Context(prec=28, rounding=ROUND_HALF_EVEN, Emin=-999999, Emax=999999,\n",
    "# capitals=1, clamp=0, flags=[], \n",
    "# traps=[InvalidOperation, DivisionByZero, Overflow])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "output_type": "stream",
     "name": "stdout",
     "text": [
      "0.3333333333333333333333333333\n"
     ]
    }
   ],
   "source": [
    "b = Decimal(1) / Decimal(3)\n",
    "print(b)\n",
    "# 0.3333333333333333333333333333"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "【例子】使 1/3 保留 4 位，用 `getcontext().prec` 来调整精度。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0.3333\n"
     ]
    }
   ],
   "source": [
    "decimal.getcontext().prec = 4\n",
    "c = Decimal(1) / Decimal(3)\n",
    "print(c)\n",
    "\n",
    "# 0.3333"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "<b>布尔型</b>\n",
    "\n",
    "布尔 (boolean) 型变量只能取两个值，`True` 和 `False`。当把布尔型变量用在数字运算中，用 `1` 和 `0` 代表 `True` 和 `False`。\n",
    "\n",
    "【例子】"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "2\n",
      "1\n",
      "0\n"
     ]
    }
   ],
   "source": [
    "print(True + True)  # 2\n",
    "print(True + False)  # 1\n",
    "print(True * False)  # 0"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "\n",
    "\n",
    "除了直接给变量赋值 `True` 和 `False`，还可以用 `bool(X)` 来创建变量，其中 `X` 可以是\n",
    "\n",
    "- 基本类型：整型、浮点型、布尔型\n",
    "- 容器类型：字符串、元组、列表、字典和集合\n",
    "\n",
    "【例子】`bool` 作用在基本类型变量：`X` 只要不是整型 `0`、浮点型 `0.0`，`bool(X)` 就是 `True`，其余就是 `False`。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "output_type": "stream",
     "name": "stdout",
     "text": [
      "<class 'int'> False True\nTrue\n<class 'float'> False True\n<class 'bool'> False True\n"
     ]
    }
   ],
   "source": [
    "print(type(0), bool(0), bool(1))\n",
    "# <class 'int'> False True\n",
    "print(type(10.31), bool(0.00), bool(10.31))\n",
    "# <class 'float'> False True\n",
    "\n",
    "print(type(True), bool(False), bool(True))\n",
    "# <class 'bool'> False True"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "\n",
    "【例子】`bool` 作用在容器类型变量：`X` 只要不是空的变量，`bool(X)` 就是 `True`，其余就是 `False`。\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<class 'str'> False True\n",
      "<class 'tuple'> False True\n",
      "<class 'list'> False True\n",
      "<class 'dict'> False True\n",
      "<class 'set'> False True\n"
     ]
    }
   ],
   "source": [
    "print(type(''), bool(''), bool('python'))\n",
    "# <class 'str'> False True\n",
    "\n",
    "print(type(()), bool(()), bool((10,)))\n",
    "# <class 'tuple'> False True\n",
    "\n",
    "print(type([]), bool([]), bool([1, 2]))\n",
    "# <class 'list'> False True\n",
    "\n",
    "print(type({}), bool({}), bool({'a': 1, 'b': 2}))\n",
    "# <class 'dict'> False True\n",
    "\n",
    "print(type(set()), bool(set()), bool({1, 2}))\n",
    "# <class 'set'> False True"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "\n",
    "确定`bool(X)` 的值是 `True` 还是 `False`，就看 `X` 是不是空，空的话就是 `False`，不空的话就是 `True`。\n",
    "\n",
    "- 对于数值变量，`0`, `0.0` 都可认为是空的。\n",
    "- 对于容器变量，里面没元素就是空的。\n",
    "\n",
    "\n",
    "<b>获取类型信息</b>\n",
    "\n",
    "- 获取类型信息 `type(object)`\n",
    "\n",
    "【例子】"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "True\n",
      "True\n",
      "True\n",
      "True\n"
     ]
    }
   ],
   "source": [
    "print(isinstance(1, int))  # True\n",
    "print(isinstance(5.2, float))  # True\n",
    "print(isinstance(True, bool))  # True\n",
    "print(isinstance('5.2', str))  # True"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "注：\n",
    "- `type()` 不会认为子类是一种父类类型，不考虑继承关系。\n",
    "- `isinstance()` 会认为子类是一种父类类型，考虑继承关系。\n",
    "\n",
    "如果要判断两个类型是否相同推荐使用 `isinstance()`。\n",
    "\n",
    "\n",
    "**类型转换**\n",
    "\n",
    "- 转换为整型 `int(x, base=10)`\n",
    "- 转换为字符串 `str(object='')`\n",
    "- 转换为浮点型 `float(x)`\n",
    "\n",
    "【例子】"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "520\n",
      "520\n",
      "520.52\n",
      "520.0\n",
      "20\n",
      "15.3\n"
     ]
    }
   ],
   "source": [
    "print(int('520'))  # 520\n",
    "print(int(520.52))  # 520\n",
    "print(float('520.52'))  # 520.52\n",
    "print(float(520))  # 520.0\n",
    "print(str(10 + 10))  # 20\n",
    "print(str(10.1 + 5.2))  # 15.3"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "## 5. print() 函数\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "print(*objects, sep=' ', end='\\n', file=sys.stdout, flush=False)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "- 将对象以字符串表示的方式格式化输出到流文件对象file里。其中所有非关键字参数都按`str()`方式进行转换为字符串输出；\n",
    "- 关键字参数`sep`是实现分隔符，比如多个参数输出时想要输出中间的分隔字符；\n",
    "- 关键字参数`end`是输出结束时的字符，默认是换行符`\\n`；\n",
    "- 关键字参数`file`是定义流输出的文件，可以是标准的系统输出`sys.stdout`，也可以重定义为别的文件；\n",
    "- 关键字参数`flush`是立即把内容输出到流文件，不作缓存。\n",
    "\n",
    "【例子】没有参数时，每次输出后都会换行。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "This is printed without 'end'and 'sep'.\n",
      "apple\n",
      "mango\n",
      "carrot\n",
      "banana\n"
     ]
    }
   ],
   "source": [
    "shoplist = ['apple', 'mango', 'carrot', 'banana']\n",
    "print(\"This is printed without 'end'and 'sep'.\")\n",
    "for item in shoplist:\n",
    "    print(item)\n",
    "\n",
    "# This is printed without 'end'and 'sep'.\n",
    "# apple\n",
    "# mango\n",
    "# carrot\n",
    "# banana"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "【例子】每次输出结束都用`end`设置的参数`&`结尾，并没有默认换行。\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "This is printed with 'end='&''.\n",
      "apple&mango&carrot&banana&hello world\n"
     ]
    }
   ],
   "source": [
    "shoplist = ['apple', 'mango', 'carrot', 'banana']\n",
    "print(\"This is printed with 'end='&''.\")\n",
    "for item in shoplist:\n",
    "    print(item, end='&')\n",
    "print('hello world')\n",
    "\n",
    "# This is printed with 'end='&''.\n",
    "# apple&mango&carrot&banana&hello world"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "\n",
    "【例子】`item`值与`'another string'`两个值之间用`sep`设置的参数`&`分割。由于`end`参数没有设置，因此默认是输出解释后换行，即`end`参数的默认值为`\\n`。\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "This is printed with 'sep='&''.\n",
      "apple&another string\n",
      "mango&another string\n",
      "carrot&another string\n",
      "banana&another string\n"
     ]
    }
   ],
   "source": [
    "shoplist = ['apple', 'mango', 'carrot', 'banana']\n",
    "print(\"This is printed with 'sep='&''.\")\n",
    "for item in shoplist:\n",
    "    print(item, 'another string', sep='&')\n",
    "\n",
    "# This is printed with 'sep='&''.\n",
    "# apple&another string\n",
    "# mango&another string\n",
    "# carrot&another string\n",
    "# banana&another string"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "\n",
    "# 位运算\n",
    "\n",
    "## 1. 原码、反码和补码\n",
    "\n",
    "二进制有三种不同的表示形式：原码、反码和补码，<u>计算机内部使用补码来表示</u>。\n",
    "\n",
    "**原码**：就是其二进制表示（注意，有一位符号位）。\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "```python\n",
    "00 00 00 11 -> 3\n",
    "10 00 00 11 -> -3\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**反码**：正数的反码就是原码，负数的反码是符号位不变，其余位取反（对应正数按位取反）。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "```python\n",
    "00 00 00 11 -> 3\n",
    "11 11 11 00 -> -3\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**补码**：正数的补码就是原码，负数的补码是反码+1。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "```python\n",
    "00 00 00 11 -> 3\n",
    "11 11 11 01 -> -3\n",
    "```\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**符号位**：最高位为符号位，0表示正数，1表示负数。在位运算中符号位也参与运算。\n",
    "\n",
    "\n",
    "## 2. 按位运算"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "- 按位非操作 ~\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "```python\n",
    "~ 1 = 0\n",
    "~ 0 = 1\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "`~` 把`num`的补码中的 0 和 1 全部取反（0 变为 1，1 变为 0）有符号整数的符号位在 `~` 运算中同样会取反。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "```python\n",
    "00 00 01 01 -> 5\n",
    "~\n",
    "---\n",
    "11 11 10 10 -> -6\n",
    "\n",
    "11 11 10 11 -> -5\n",
    "~\n",
    "---\n",
    "00 00 01 00 -> 4\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "- 按位与操作 &  "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "```python\n",
    "1 & 1 = 1\n",
    "1 & 0 = 0\n",
    "0 & 1 = 0\n",
    "0 & 0 = 0\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "只有两个对应位都为 1 时才为 1"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "```python\n",
    "00 00 01 01 -> 5\n",
    "&\n",
    "00 00 01 10 -> 6\n",
    "---\n",
    "00 00 01 00 -> 4\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "- 按位或操作 |"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "\n",
    "```python\n",
    "1 | 1 = 1\n",
    "1 | 0 = 1\n",
    "0 | 1 = 1\n",
    "0 | 0 = 0\n",
    "```\n",
    "\n",
    "只要两个对应位中有一个 1 时就为 1\n",
    "```python\n",
    "00 00 01 01 -> 5\n",
    "|\n",
    "00 00 01 10 -> 6\n",
    "---\n",
    "00 00 01 11 -> 7\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "- 按位异或操作 ^"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "\n",
    "\n",
    "```python\n",
    "1 ^ 1 = 0\n",
    "1 ^ 0 = 1\n",
    "0 ^ 1 = 1\n",
    "0 ^ 0 = 0\n",
    "```\n",
    "\n",
    "只有两个对应位不同时才为 1\n",
    "\n",
    "```python\n",
    "00 00 01 01 -> 5\n",
    "^\n",
    "00 00 01 10 -> 6\n",
    "---\n",
    "00 00 00 11 -> 3\n",
    "```\n",
    "\n",
    "异或操作的性质：满足交换律和结合律\n",
    "```python\n",
    "A: 00 00 11 00\n",
    "B: 00 00 01 11\n",
    "\n",
    "A^B: 00 00 10 11\n",
    "B^A: 00 00 10 11\n",
    "\n",
    "A^A: 00 00 00 00\n",
    "A^0: 00 00 11 00\n",
    "\n",
    "A^B^A: = A^A^B = B = 00 00 01 11\n",
    "```\n",
    "\n",
    "\n",
    "- 按位左移操作 <<\n",
    "\n",
    "`num << i` 将`num`的二进制表示向左移动`i`位所得的值。\n",
    "\n",
    "```python\n",
    "00 00 10 11 -> 11\n",
    "11 << 3\n",
    "---\n",
    "01 01 10 00 -> 88 \n",
    "```\n",
    "\n",
    "- 按位右移操作 >>\n",
    "\n",
    "`num >> i` 将`num`的二进制表示向右移动`i`位所得的值。\n",
    "```python\n",
    "00 00 10 11 -> 11\n",
    "11 >> 2\n",
    "---\n",
    "00 00 00 10 -> 2 \n",
    "```\n",
    "\n",
    "## 3. 利用位运算实现快速计算\n",
    "\n",
    "通过 `<<`，`>>` 快速计算2的倍数问题。\n",
    "\n",
    "```python\n",
    "n << 1 -> 计算 n*2\n",
    "n >> 1 -> 计算 n/2，负奇数的运算不可用\n",
    "n << m -> 计算 n*(2^m)，即乘以 2 的 m 次方\n",
    "n >> m -> 计算 n/(2^m)，即除以 2 的 m 次方\n",
    "1 << n -> 2^n\n",
    "```\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "通过 `^` 快速交换两个整数。\n",
    "通过 `^` 快速交换两个整数。\n",
    "```python\n",
    "a ^= b\n",
    "b ^= a\n",
    "a ^= b\n",
    "```\n",
    "\n",
    "通过 `a & (-a)` 快速获取`a`的最后为 1 位置的整数。\n",
    "\n",
    "```python\n",
    "00 00 01 01 -> 5\n",
    "&\n",
    "11 11 10 11 -> -5\n",
    "---\n",
    "00 00 00 01 -> 1\n",
    "\n",
    "00 00 11 10 -> 14\n",
    "&\n",
    "11 11 00 10 -> -14\n",
    "---\n",
    "00 00 00 10 -> 2\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 4. 利用位运算实现整数集合\n",
    "\n",
    "一个数的二进制表示可以看作是一个集合（0 表示不在集合中，1 表示在集合中）。\n",
    "\n",
    "比如集合 `{1, 3, 4, 8}`，可以表示成 `01 00 01 10 10` 而对应的位运算也就可以看作是对集合进行的操作。\n",
    "\n",
    "元素与集合的操作：\n",
    "```python\n",
    "a | (1<<i)  -> 把 i 插入到集合中\n",
    "a & ~(1<<i) -> 把 i 从集合中删除\n",
    "a & (1<<i)  -> 判断 i 是否属于该集合（零不属于，非零属于）\n",
    "```\n",
    "\n",
    "集合之间的操作：\n",
    "```python\n",
    "a 补   -> ~a\n",
    "a 交 b -> a & b\n",
    "a 并 b -> a | b\n",
    "a 差 b -> a & (~b)\n",
    "```\n",
    "\n",
    "\n",
    "注意：整数在内存中是以补码的形式存在的，输出自然也是按照补码输出。\n",
    "\n",
    "【例子】C#语言输出负数。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "output_type": "error",
     "ename": "SyntaxError",
     "evalue": "invalid syntax (<ipython-input-9-2311d5f298bb>, line 1)",
     "traceback": [
      "\u001b[1;36m  File \u001b[1;32m\"<ipython-input-9-2311d5f298bb>\"\u001b[1;36m, line \u001b[1;32m1\u001b[0m\n\u001b[1;33m    class Program\u001b[0m\n\u001b[1;37m                 ^\u001b[0m\n\u001b[1;31mSyntaxError\u001b[0m\u001b[1;31m:\u001b[0m invalid syntax\n"
     ]
    }
   ],
   "source": [
    "class Program\n",
    "{\n",
    "    static void Main(string[] args)\n",
    "    {\n",
    "        string s1 = Convert.ToString(-3, 2);\n",
    "        Console.WriteLine(s1); \n",
    "        // 11111111111111111111111111111101\n",
    "        \n",
    "        string s2 = Convert.ToString(-3, 16);\n",
    "        Console.WriteLine(s2); \n",
    "        // fffffffd\n",
    "    }\n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "【例子】 Python 的`bin()` 输出。\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0b11\n",
      "-0b11\n",
      "0b11111111111111111111111111111101\n",
      "0b11111111111111111111111111111101\n",
      "4294967293\n"
     ]
    }
   ],
   "source": [
    "print(bin(3))  # 0b11\n",
    "print(bin(-3))  # -0b11\n",
    "\n",
    "print(bin(-3 & 0xffffffff))  \n",
    "# 0b11111111111111111111111111111101\n",
    "\n",
    "print(bin(0xfffffffd))       \n",
    "# 0b11111111111111111111111111111101\n",
    "\n",
    "print(0xfffffffd)  # 4294967293"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "是不是很颠覆认知，我们从结果可以看出：\n",
    "\n",
    "- Python中`bin`一个负数（十进制表示），输出的是它的原码的二进制表示加上个负号，巨坑。\n",
    "- Python中的整型是补码形式存储的。\n",
    "- Python中整型是不限制长度的不会超范围溢出。\n",
    "\n",
    "所以为了获得负数（十进制表示）的补码，需要手动将其和十六进制数`0xffffffff`进行按位与操作，再交给`bin()`进行输出，得到的才是负数的补码表示。\n",
    "\n",
    "# 条件语句\n",
    "\n",
    "## 1. if 语句\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "```python\n",
    "if expression:\n",
    "    expr_true_suite\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "- if 语句的 `expr_true_suite` 代码块只有当条件表达式 `expression` 结果为真时才执行，否则将继续执行紧跟在该代码块后面的语句。\n",
    "- 单个 if 语句中的 `expression` 条件表达式可以通过布尔操作符 `and`，`or`和`not` 实现多重条件判断。\n",
    "\n",
    "【例子】"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 38,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Correct Judgement!\n"
     ]
    }
   ],
   "source": [
    "if 2 > 1 and not 2 > 3:\n",
    "    print('Correct Judgement!')\n",
    "\n",
    "# Correct Judgement!"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "\n",
    "\n",
    "## 2. if - else 语句\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "```python\n",
    "if expression:\n",
    "    expr_true_suite\n",
    "else:\n",
    "    expr_false_suite\n",
    "```\n",
    "- Python 提供与 if 搭配使用的 else，如果 if 语句的条件表达式结果布尔值为假，那么程序将执行 else 语句后的代码。\n",
    "\n",
    "【例子】"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "猜一猜小姐姐想的是哪个数字？666\n",
      "你太了解小姐姐的心思了！\n",
      "哼，猜对也没有奖励！\n",
      "游戏结束，不玩儿啦！\n"
     ]
    }
   ],
   "source": [
    "temp = input(\"猜一猜小姐姐想的是哪个数字？\")\n",
    "guess = int(temp) # input 函数将接收的任何数据类型都默认为 str。\n",
    "if guess == 666:\n",
    "    print(\"你太了解小姐姐的心思了！\")\n",
    "    print(\"哼，猜对也没有奖励！\")\n",
    "else:\n",
    "    print(\"猜错了，小姐姐现在心里想的是666！\")\n",
    "print(\"游戏结束，不玩儿啦！\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "\n",
    "\n",
    "`if`语句支持嵌套，即在一个`if`语句中嵌入另一个`if`语句，从而构成不同层次的选择结构。\n",
    "\n",
    "【例子】Python 使用缩进而不是大括号来标记代码块边界，因此要特别注意`else`的悬挂问题。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "metadata": {},
   "outputs": [],
   "source": [
    "hi = 6\n",
    "if hi > 2:\n",
    "    if hi > 7:\n",
    "        print('好棒!好棒!')\n",
    "else:\n",
    "    print('切~')\n",
    "\n",
    "# 无输出"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "\n",
    "【例子】"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "猜一猜小姐姐想的是哪个数字？8\n",
      "你太了解小姐姐的心思了！\n",
      "哼，猜对也没有奖励！\n",
      "游戏结束，不玩儿啦！\n"
     ]
    }
   ],
   "source": [
    "temp = input(\"猜一猜小姐姐想的是哪个数字？\")\n",
    "guess = int(temp)\n",
    "if guess > 8:\n",
    "    print(\"大了，大了\")\n",
    "else:\n",
    "    if guess == 8:\n",
    "        print(\"你太了解小姐姐的心思了！\")\n",
    "        print(\"哼，猜对也没有奖励！\")\n",
    "    else:\n",
    "        print(\"小了，小了\")\n",
    "print(\"游戏结束，不玩儿啦！\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "\n",
    "## 3. if - elif - else 语句\n",
    "\n",
    "```python\n",
    "if expression1:\n",
    "    expr1_true_suite\n",
    "elif expression2:\n",
    "    expr2_true_suite\n",
    "    .\n",
    "    .\n",
    "elif expressionN:\n",
    "    exprN_true_suite\n",
    "else:\n",
    "    expr_false_suite\n",
    "```\n",
    "\n",
    "- elif 语句即为 else if，用来检查多个表达式是否为真，并在为真时执行特定代码块中的代码。\n",
    "\n",
    "【例子】"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 42,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "请输入成绩:99\n",
      "A\n"
     ]
    }
   ],
   "source": [
    "temp = input('请输入成绩:')\n",
    "source = int(temp)\n",
    "if 100 >= source >= 90:\n",
    "    print('A')\n",
    "elif 90 > source >= 80:\n",
    "    print('B')\n",
    "elif 80 > source >= 60:\n",
    "    print('C')\n",
    "elif 60 > source >= 0:\n",
    "    print('D')\n",
    "else:\n",
    "    print('输入错误！')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 4. assert 关键词\n",
    "\n",
    "- `assert`这个关键词我们称之为“断言”，当这个关键词后边的条件为 False 时，程序自动崩溃并抛出`AssertionError`的异常。\n",
    "\n",
    "【例子】"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "output_type": "error",
     "ename": "AssertionError",
     "evalue": "",
     "traceback": [
      "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[1;31mAssertionError\u001b[0m                            Traceback (most recent call last)",
      "\u001b[1;32m<ipython-input-10-d6a31436682c>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m\u001b[0m\n\u001b[0;32m      1\u001b[0m \u001b[0mmy_list\u001b[0m \u001b[1;33m=\u001b[0m \u001b[1;33m[\u001b[0m\u001b[1;34m'lsgogroup'\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m      2\u001b[0m \u001b[0mmy_list\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mpop\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;36m0\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 3\u001b[1;33m \u001b[1;32massert\u001b[0m \u001b[0mlen\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mmy_list\u001b[0m\u001b[1;33m)\u001b[0m \u001b[1;33m>\u001b[0m \u001b[1;36m0\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m      4\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m      5\u001b[0m \u001b[1;31m# AssertionError\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
      "\u001b[1;31mAssertionError\u001b[0m: "
     ]
    }
   ],
   "source": [
    "my_list = ['lsgogroup']\n",
    "my_list.pop(0)\n",
    "assert len(my_list) > 0\n",
    "\n",
    "# AssertionError"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "【例子】在进行单元测试时，可以用来在程序中置入检查点，只有条件为 True 才能让程序正常工作。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "assert 3 > 7\n",
    "\n",
    "# AssertionError"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 循环语句\n",
    "\n",
    "\n",
    "## 1. while 循环\n",
    "\n",
    "`while`语句最基本的形式包括一个位于顶部的布尔表达式，一个或多个属于`while`代码块的缩进语句。\n",
    "\n",
    "```python\n",
    "while 布尔表达式:\n",
    "    代码块\n",
    "```\n",
    "\n",
    "`while`循环的代码块会一直循环执行，直到布尔表达式的值为布尔假。\n",
    "\n",
    "如果布尔表达式不带有`<、>、==、！=、in、not in`等运算符，仅仅给出数值之类的条件，也是可以的。当`while`后写入一个非零整数时，视为真值，执行循环体；写入`0`时，视为假值，不执行循环体。也可以写入`str、list`或任何序列，长度非零则视为真值，执行循环体；否则视为假值，不执行循环体。\n",
    "\n",
    "【例子】"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 44,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "猜一猜小姐姐想的是哪个数字？8\n",
      "你太了解小姐姐的心思了！\n",
      "哼，猜对也没有奖励！\n",
      "游戏结束，不玩儿啦！\n"
     ]
    }
   ],
   "source": [
    "count = 0\n",
    "while count < 3:\n",
    "    temp = input(\"猜一猜小姐姐想的是哪个数字？\")\n",
    "    guess = int(temp)\n",
    "    if guess > 8:\n",
    "        print(\"大了，大了\")\n",
    "    else:\n",
    "        if guess == 8:\n",
    "            print(\"你太了解小姐姐的心思了！\")\n",
    "            print(\"哼，猜对也没有奖励！\")\n",
    "            count = 3\n",
    "        else:\n",
    "            print(\"小了，小了\")\n",
    "    count = count + 1\n",
    "print(\"游戏结束，不玩儿啦！\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "【例子】布尔表达式返回0，循环终止。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 45,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "abcd\n",
      "bcd\n",
      "cd\n",
      "d\n"
     ]
    }
   ],
   "source": [
    "string = 'abcd'\n",
    "while string:\n",
    "    print(string)\n",
    "    string = string[1:]\n",
    "\n",
    "# abcd\n",
    "# bcd\n",
    "# cd\n",
    "# d"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "---\n",
    "## 2. while - else 循环\n",
    "\n",
    "```python\n",
    "while 布尔表达式:\n",
    "    代码块\n",
    "else:\n",
    "    代码块\n",
    "```\n",
    "\n",
    "当`while`循环正常执行完的情况下，执行`else`输出，如果`while`循环中执行了跳出循环的语句，比如 `break`，将不执行`else`代码块的内容。    \n",
    "\n",
    "【例子】"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 46,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0 is  less than 5\n",
      "1 is  less than 5\n",
      "2 is  less than 5\n",
      "3 is  less than 5\n",
      "4 is  less than 5\n",
      "5 is not less than 5\n"
     ]
    }
   ],
   "source": [
    "count = 0\n",
    "while count < 5:\n",
    "    print(\"%d is  less than 5\" % count)\n",
    "    count = count + 1\n",
    "else:\n",
    "    print(\"%d is not less than 5\" % count)\n",
    "    \n",
    "# 0 is  less than 5\n",
    "# 1 is  less than 5\n",
    "# 2 is  less than 5\n",
    "# 3 is  less than 5\n",
    "# 4 is  less than 5\n",
    "# 5 is not less than 5"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "【例子】"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 47,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0 is  less than 5\n"
     ]
    }
   ],
   "source": [
    "count = 0\n",
    "while count < 5:\n",
    "    print(\"%d is  less than 5\" % count)\n",
    "    count = 6\n",
    "    break\n",
    "else:\n",
    "    print(\"%d is not less than 5\" % count)\n",
    "\n",
    "# 0 is  less than 5"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "---\n",
    "## 3. for 循环\n",
    "\n",
    "`for`循环是迭代循环，在Python中相当于一个通用的序列迭代器，可以遍历任何有序序列，如`str、list、tuple`等，也可以遍历任何可迭代对象，如`dict`。\n",
    "\n",
    "```python\n",
    "for 迭代变量 in 可迭代对象:\n",
    "    代码块\n",
    "```\n",
    "每次循环，迭代变量被设置为可迭代对象的当前元素，提供给代码块使用。\n",
    "\n",
    "【例子】"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 48,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "I L o v e L S G O "
     ]
    }
   ],
   "source": [
    "for i in 'ILoveLSGO':\n",
    "    print(i, end=' ')  # 不换行输出\n",
    "\n",
    "# I L o v e L S G O"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "【例子】"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 49,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "张三\n",
      "李四\n",
      "刘德华\n",
      "刘六\n",
      "周润发\n",
      "张三\n",
      "李四\n",
      "刘德华\n",
      "刘六\n",
      "周润发\n"
     ]
    }
   ],
   "source": [
    "member = ['张三', '李四', '刘德华', '刘六', '周润发']\n",
    "for each in member:\n",
    "    print(each)\n",
    "\n",
    "# 张三\n",
    "# 李四\n",
    "# 刘德华\n",
    "# 刘六\n",
    "# 周润发\n",
    "\n",
    "for i in range(len(member)):\n",
    "    print(member[i])\n",
    "\n",
    "# 张三\n",
    "# 李四\n",
    "# 刘德华\n",
    "# 刘六\n",
    "# 周润发"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "【例子】"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 50,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "a:1 b:2 c:3 d:4 "
     ]
    }
   ],
   "source": [
    "dic = {'a': 1, 'b': 2, 'c': 3, 'd': 4}\n",
    "\n",
    "for key, value in dic.items():\n",
    "    print(key, value, sep=':', end=' ')\n",
    "    \n",
    "# a:1 b:2 c:3 d:4 "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "【例子】\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "output_type": "stream",
     "name": "stdout",
     "text": [
      "1\na 2\nb 3\nc 4\nd "
     ]
    }
   ],
   "source": [
    "dic = {'a': 1, 'b': 2, 'c': 3, 'd': 4}\n",
    "\n",
    "for key in dic.keys():\n",
    "    print(key, end=' ')\n",
    "    \n",
    "# a b c d "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "【例子】"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 52,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1 2 3 4 "
     ]
    }
   ],
   "source": [
    "dic = {'a': 1, 'b': 2, 'c': 3, 'd': 4}\n",
    "\n",
    "for value in dic.values():\n",
    "    print(value, end=' ')\n",
    "    \n",
    "# 1 2 3 4"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "---\n",
    "## 4. for - else 循环\n",
    "\n",
    "```python\n",
    "for 迭代变量 in 可迭代对象:\n",
    "    代码块\n",
    "else:\n",
    "    代码块\n",
    "```\n",
    "\n",
    "当`for`循环正常执行完的情况下，执行`else`输出，如果`for`循环中执行了跳出循环的语句，比如 `break`，将不执行`else`代码块的内容，与`while - else`语句一样。\n",
    "\n",
    "【例子】"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 53,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "10 等于 2 * 5\n",
      "11 是一个质数\n",
      "12 等于 2 * 6\n",
      "13 是一个质数\n",
      "14 等于 2 * 7\n",
      "15 等于 3 * 5\n",
      "16 等于 2 * 8\n",
      "17 是一个质数\n",
      "18 等于 2 * 9\n",
      "19 是一个质数\n"
     ]
    }
   ],
   "source": [
    "for num in range(10, 20):  # 迭代 10 到 20 之间的数字\n",
    "    for i in range(2, num):  # 根据因子迭代\n",
    "        if num % i == 0:  # 确定第一个因子\n",
    "            j = num / i  # 计算第二个因子\n",
    "            print('%d 等于 %d * %d' % (num, i, j))\n",
    "            break  # 跳出当前循环\n",
    "    else:  # 循环的 else 部分\n",
    "        print(num, '是一个质数')\n",
    "\n",
    "# 10 等于 2 * 5\n",
    "# 11 是一个质数\n",
    "# 12 等于 2 * 6\n",
    "# 13 是一个质数\n",
    "# 14 等于 2 * 7\n",
    "# 15 等于 3 * 5\n",
    "# 16 等于 2 * 8\n",
    "# 17 是一个质数\n",
    "# 18 等于 2 * 9\n",
    "# 19 是一个质数"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "---\n",
    "## 5. range() 函数\n",
    "\n",
    "```python\n",
    "range([start,] stop[, step=1])\n",
    "```\n",
    "- 这个BIF（Built-in functions）有三个参数，其中用中括号括起来的两个表示这两个参数是可选的。\n",
    "- `step=1` 表示第三个参数的默认值是1。\n",
    "- `range` 这个BIF的作用是生成一个从`start`参数的值开始到`stop`参数的值结束的数字序列，该序列包含`start`的值但不包含`stop`的值。\n",
    "\n",
    "【例子】"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 54,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "2\n",
      "3\n",
      "4\n",
      "5\n",
      "6\n",
      "7\n",
      "8\n"
     ]
    }
   ],
   "source": [
    "for i in range(2, 9):  # 不包含9\n",
    "    print(i)\n",
    "\n",
    "# 2\n",
    "# 3\n",
    "# 4\n",
    "# 5\n",
    "# 6\n",
    "# 7\n",
    "# 8"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "【例子】"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 55,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1\n",
      "3\n",
      "5\n",
      "7\n",
      "9\n"
     ]
    }
   ],
   "source": [
    "for i in range(1, 10, 2):\n",
    "    print(i)\n",
    "\n",
    "# 1\n",
    "# 3\n",
    "# 5\n",
    "# 7\n",
    "# 9"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "---\n",
    "## 6. enumerate()函数\n",
    "\n",
    "```python\n",
    "enumerate(sequence, [start=0])\n",
    "```\n",
    "- sequence：一个序列、迭代器或其他支持迭代对象。\n",
    "- start：下标起始位置。\n",
    "- 返回 enumerate(枚举) 对象\n",
    "\n",
    "【例子】"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 56,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[(0, 'Spring'), (1, 'Summer'), (2, 'Fall'), (3, 'Winter')]\n",
      "[(1, 'Spring'), (2, 'Summer'), (3, 'Fall'), (4, 'Winter')]\n"
     ]
    }
   ],
   "source": [
    "seasons = ['Spring', 'Summer', 'Fall', 'Winter']\n",
    "lst = list(enumerate(seasons))\n",
    "print(lst)\n",
    "# [(0, 'Spring'), (1, 'Summer'), (2, 'Fall'), (3, 'Winter')]\n",
    "lst = list(enumerate(seasons, start=1))  # 下标从 1 开始\n",
    "print(lst)\n",
    "# [(1, 'Spring'), (2, 'Summer'), (3, 'Fall'), (4, 'Winter')]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "`enumerate()`与 for 循环的结合使用。\n",
    "\n",
    "```python\n",
    "for i, a in enumerate(A)\n",
    "    do something with a  \n",
    "```\n",
    "用 `enumerate(A)` 不仅返回了 `A` 中的元素，还顺便给该元素一个索引值 (默认从 0 开始)。此外，用 `enumerate(A, j)` 还可以确定索引起始值为 `j`。\n",
    "\n",
    "【例子】"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 57,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "I love Python\n",
      "I love R\n",
      "I love Matlab\n",
      "I love C++\n",
      "Done!\n",
      "2 I love Python\n",
      "3 I love R\n",
      "4 I love Matlab\n",
      "5 I love C++\n",
      "Done!\n"
     ]
    }
   ],
   "source": [
    "languages = ['Python', 'R', 'Matlab', 'C++']\n",
    "for language in languages:\n",
    "    print('I love', language)\n",
    "print('Done!')\n",
    "# I love Python\n",
    "# I love R\n",
    "# I love Matlab\n",
    "# I love C++\n",
    "# Done!\n",
    "\n",
    "\n",
    "for i, language in enumerate(languages, 2):\n",
    "    print(i, 'I love', language)\n",
    "print('Done!')\n",
    "# 2 I love Python\n",
    "# 3 I love R\n",
    "# 4 I love Matlab\n",
    "# 5 I love C++\n",
    "# Done!"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "---\n",
    "## 7. break 语句\n",
    "\n",
    "`break`语句可以跳出当前所在层的循环。\n",
    "\n",
    "【例子】\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 59,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "猜一猜小姐姐想的是哪个数字？8\n",
      "你太了解小姐姐的心思了！\n",
      "哼，猜对也没有奖励！\n",
      "游戏结束，不玩儿啦！\n"
     ]
    }
   ],
   "source": [
    "import random\n",
    "secret = random.randint(1, 10) #[1,10]之间的随机数\n",
    "\n",
    "while True:\n",
    "    temp = input(\"猜一猜小姐姐想的是哪个数字？\")\n",
    "    guess = int(temp)\n",
    "    if guess > secret:\n",
    "        print(\"大了，大了\")\n",
    "    else:\n",
    "        if guess == secret:\n",
    "            print(\"你太了解小姐姐的心思了！\")\n",
    "            print(\"哼，猜对也没有奖励！\")\n",
    "            break\n",
    "        else:\n",
    "            print(\"小了，小了\")\n",
    "print(\"游戏结束，不玩儿啦！\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "---\n",
    "## 8. continue 语句\n",
    "\n",
    "`continue`终止本轮循环并开始下一轮循环。\n",
    "\n",
    "【例子】"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 60,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "2\n",
      "1\n",
      "4\n",
      "3\n",
      "6\n",
      "5\n",
      "8\n",
      "7\n",
      "10\n",
      "9\n"
     ]
    }
   ],
   "source": [
    "for i in range(10):\n",
    "    if i % 2 != 0:\n",
    "        print(i)\n",
    "        continue\n",
    "    i += 2\n",
    "    print(i)\n",
    "\n",
    "# 2\n",
    "# 1\n",
    "# 4\n",
    "# 3\n",
    "# 6\n",
    "# 5\n",
    "# 8\n",
    "# 7\n",
    "# 10\n",
    "# 9"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "---\n",
    "## 9. pass 语句\n",
    "\n",
    "`pass` 语句的意思是“不做任何事”，如果你在需要有语句的地方不写任何语句，那么解释器会提示出错，而 `pass` 语句就是用来解决这些问题的。\n",
    "\n",
    "【例子】"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def a_func():\n",
    "\n",
    "# SyntaxError: unexpected EOF while parsing"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "【例子】\n",
    "\n",
    "```python\n",
    "def a_func():\n",
    "    pass\n",
    "```\n",
    "`pass`是空语句，不做任何操作，只起到占位的作用，其作用是为了保持程序结构的完整性。尽管`pass`语句不做任何操作，但如果暂时不确定要在一个位置放上什么样的代码，可以先放置一个`pass`语句，让代码可以正常运行。\n",
    "\n",
    "---\n",
    "## 10. 推导式\n",
    "\n",
    "\n",
    "**列表推导式**\n",
    "\n",
    "```python\n",
    "[ expr for value in collection [if condition] ]\n",
    "```\n",
    "\n",
    "【例子】"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 61,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[-8, -4, 0, 4, 8]\n"
     ]
    }
   ],
   "source": [
    "x = [-4, -2, 0, 2, 4]\n",
    "y = [a * 2 for a in x]\n",
    "print(y)\n",
    "# [-8, -4, 0, 4, 8]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "【例子】"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 63,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[1, 4, 9, 16, 25, 36, 49, 64, 81]\n"
     ]
    }
   ],
   "source": [
    "x = [i ** 2 for i in range(1, 10)]\n",
    "print(x)\n",
    "# [1, 4, 9, 16, 25, 36, 49, 64, 81]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "\n",
    "【例子】"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 64,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[(0, 0), (1, 1), (2, 4), (3, 9), (4, 16), (5, 25)]\n"
     ]
    }
   ],
   "source": [
    "x = [(i, i ** 2) for i in range(6)]\n",
    "print(x)\n",
    "\n",
    "# [(0, 0), (1, 1), (2, 4), (3, 9), (4, 16), (5, 25)]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "【例子】\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 65,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[3, 9, 15, 21, 27, 33, 39, 45, 51, 57, 63, 69, 75, 81, 87, 93, 99]\n"
     ]
    }
   ],
   "source": [
    "x = [i for i in range(100) if (i % 2) != 0 and (i % 3) == 0]\n",
    "print(x)\n",
    "\n",
    "# [3, 9, 15, 21, 27, 33, 39, 45, 51, 57, 63, 69, 75, 81, 87, 93, 99]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "【例子】\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 66,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[(0, 0), (0, 1), (0, 2), (1, 0), (1, 1), (1, 2), (2, 0), (2, 1), (2, 2)]\n"
     ]
    }
   ],
   "source": [
    "a = [(i, j) for i in range(0, 3) for j in range(0, 3)]\n",
    "print(a)\n",
    "\n",
    "# [(0, 0), (0, 1), (0, 2), (1, 0), (1, 1), (1, 2), (2, 0), (2, 1), (2, 2)]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "【例子】"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 67,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[0, 0], [0, 1], [0, 2], [1, 0], [1, 1], [1, 2], [2, 0], [2, 1], [2, 2]]\n",
      "[[10, 0], [0, 1], [0, 2], [1, 0], [1, 1], [1, 2], [2, 0], [2, 1], [2, 2]]\n"
     ]
    }
   ],
   "source": [
    "x = [[i, j] for i in range(0, 3) for j in range(0, 3)]\n",
    "print(x)\n",
    "# [[0, 0], [0, 1], [0, 2], [1, 0], [1, 1], [1, 2], [2, 0], [2, 1], [2, 2]]\n",
    "\n",
    "x[0][0] = 10\n",
    "print(x)\n",
    "# [[10, 0], [0, 1], [0, 2], [1, 0], [1, 1], [1, 2], [2, 0], [2, 1], [2, 2]]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "【例子】\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 68,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[(0, 2)]\n"
     ]
    }
   ],
   "source": [
    "a = [(i, j) for i in range(0, 3) if i < 1 for j in range(0, 3) if j > 1]\n",
    "print(a)\n",
    "\n",
    "# [(0, 2)]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "**元组推导式**\n",
    "\n",
    "```python\n",
    "( expr for value in collection [if condition] )\n",
    "```\n",
    "\n",
    "【例子】"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 69,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<generator object <genexpr> at 0x0000014CEC2E28B8>\n",
      "(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)\n"
     ]
    }
   ],
   "source": [
    "a = (x for x in range(10))\n",
    "print(a)\n",
    "\n",
    "# <generator object <genexpr> at 0x0000025BE511CC48>\n",
    "\n",
    "print(tuple(a))\n",
    "\n",
    "# (0, 1, 2, 3, 4, 5, 6, 7, 8, 9)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**字典推导式**\n",
    "\n",
    "```python\n",
    "{ key_expr: value_expr for value in collection [if condition] }\n",
    "```\n",
    "\n",
    "【例子】"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 70,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{0: True, 3: False, 6: True, 9: False}\n"
     ]
    }
   ],
   "source": [
    "b = {i: i % 2 == 0 for i in range(10) if i % 3 == 0}\n",
    "print(b)\n",
    "# {0: True, 3: False, 6: True, 9: False}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "**集合推导式**\n",
    "\n",
    "```\n",
    "{ expr for value in collection [if condition] }\n",
    "```\n",
    "\n",
    "【例子】"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 71,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{1, 2, 3, 4, 5, 6}\n"
     ]
    }
   ],
   "source": [
    "c = {i for i in [1, 2, 3, 4, 5, 5, 6, 4, 3, 2, 1]}\n",
    "print(c)\n",
    "# {1, 2, 3, 4, 5, 6}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "**其它**\n",
    "\n",
    "- `next(iterator[, default])` Return the next item from the iterator. If default is given and the iterator is exhausted, it is returned instead of raising StopIteration.\n",
    "\n",
    "\n",
    "【例子】"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 72,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<generator object <genexpr> at 0x0000014CEC389C78>\n",
      "0\n",
      "1\n",
      "2 3 4 5 6 7 8 9 "
     ]
    }
   ],
   "source": [
    "e = (i for i in range(10))\n",
    "print(e)\n",
    "# <generator object <genexpr> at 0x0000007A0B8D01B0>\n",
    "\n",
    "print(next(e))  # 0\n",
    "print(next(e))  # 1\n",
    "\n",
    "for each in e:\n",
    "    print(each, end=' ')\n",
    "\n",
    "# 2 3 4 5 6 7 8 9"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "【例子】"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 73,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "5050\n",
      "5050\n"
     ]
    }
   ],
   "source": [
    "s = sum([i for i in range(101)])\n",
    "print(s)  # 5050\n",
    "s = sum((i for i in range(101)))\n",
    "print(s)  # 5050"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "\n",
    "# 异常处理\n",
    "\n",
    "异常就是运行期检测到的错误。计算机语言针对可能出现的错误定义了异常类型，某种错误引发对应的异常时，异常处理程序将被启动，从而恢复程序的正常运行。\n",
    "\n",
    "## 1. Python 标准异常总结\n",
    "\n",
    "- BaseException：所有异常的 **基类**\n",
    "- Exception：常规异常的 **基类**\n",
    "- StandardError：所有的内建标准异常的基类\n",
    "- ArithmeticError：所有数值计算异常的基类\n",
    "- FloatingPointError：浮点计算异常\n",
    "- <u>OverflowError</u>：数值运算超出最大限制\n",
    "- <u>ZeroDivisionError</u>：除数为零\n",
    "- <u>AssertionError</u>：断言语句（assert）失败\n",
    "- <u>AttributeError</u>：尝试访问未知的对象属性\n",
    "- EOFError：没有内建输入，到达EOF标记\n",
    "- EnvironmentError：操作系统异常的基类\n",
    "- IOError：输入/输出操作失败\n",
    "- <u>OSError</u>：操作系统产生的异常（例如打开一个不存在的文件）\n",
    "- WindowsError：系统调用失败\n",
    "- <u>ImportError</u>：导入模块失败的时候\n",
    "- KeyboardInterrupt：用户中断执行\n",
    "- LookupError：无效数据查询的基类\n",
    "- <u>IndexError</u>：索引超出序列的范围\n",
    "- <u>KeyError</u>：字典中查找一个不存在的关键字\n",
    "- <u>MemoryError</u>：内存溢出（可通过删除对象释放内存）\n",
    "- <u>NameError</u>：尝试访问一个不存在的变量\n",
    "- UnboundLocalError：访问未初始化的本地变量\n",
    "- ReferenceError：弱引用试图访问已经垃圾回收了的对象\n",
    "- RuntimeError：一般的运行时异常\n",
    "- NotImplementedError：尚未实现的方法\n",
    "- <u>SyntaxError</u>：语法错误导致的异常\n",
    "- IndentationError：缩进错误导致的异常\n",
    "- TabError：Tab和空格混用\n",
    "- SystemError：一般的解释器系统异常\n",
    "- <u>TypeError</u>：不同类型间的无效操作\n",
    "- <u>ValueError</u>：传入无效的参数\n",
    "- UnicodeError：Unicode相关的异常\n",
    "- UnicodeDecodeError：Unicode解码时的异常\n",
    "- UnicodeEncodeError：Unicode编码错误导致的异常\n",
    "- UnicodeTranslateError：Unicode转换错误导致的异常\n",
    "\n",
    "异常体系内部有层次关系，Python异常体系中的部分关系如下所示：\n",
    "\n",
    "\n",
    "![](https://img-blog.csdnimg.cn/20200710131404548.png)\n",
    "\n",
    "\n",
    "\n",
    "---\n",
    "## 2. Python标准警告总结\n",
    "\n",
    "- Warning：警告的基类\n",
    "- DeprecationWarning：关于被弃用的特征的警告\n",
    "- FutureWarning：关于构造将来语义会有改变的警告\n",
    "- UserWarning：用户代码生成的警告\n",
    "- PendingDeprecationWarning：关于特性将会被废弃的警告\n",
    "- RuntimeWarning：可疑的运行时行为(runtime behavior)的警告\n",
    "- SyntaxWarning：可疑语法的警告\n",
    "- ImportWarning：用于在导入模块过程中触发的警告\n",
    "- UnicodeWarning：与Unicode相关的警告\n",
    "- BytesWarning：与字节或字节码相关的警告\n",
    "- ResourceWarning：与资源使用相关的警告\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "---\n",
    "## 3. try - except 语句\n",
    "```python\n",
    "try:\n",
    "    检测范围\n",
    "except Exception[as reason]:\n",
    "    出现异常后的处理代码\n",
    "```\n",
    "\n",
    "try 语句按照如下方式工作：\n",
    "- 首先，执行`try`子句（在关键字`try`和关键字`except`之间的语句）\n",
    "- 如果没有异常发生，忽略`except`子句，`try`子句执行后结束。\n",
    "- 如果在执行`try`子句的过程中发生了异常，那么`try`子句余下的部分将被忽略。如果异常的类型和`except`之后的名称相符，那么对应的`except`子句将被执行。最后执行`try - except`语句之后的代码。\n",
    "- 如果一个异常没有与任何的`except`匹配，那么这个异常将会传递给上层的`try`中。\n",
    "\n",
    "【例子】\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "打开文件出错\n"
     ]
    }
   ],
   "source": [
    "try:\n",
    "    f = open('test.txt')\n",
    "    print(f.read())\n",
    "    f.close()\n",
    "except OSError:\n",
    "    print('打开文件出错')\n",
    "\n",
    "# 打开文件出错"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "【例子】\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "打开文件出错\n",
      "原因是：[Errno 2] No such file or directory: 'test.txt'\n"
     ]
    }
   ],
   "source": [
    "try:\n",
    "    f = open('test.txt')\n",
    "    print(f.read())\n",
    "    f.close()\n",
    "except OSError as error:\n",
    "    print('打开文件出错\\n原因是：' + str(error))\n",
    "\n",
    "# 打开文件出错\n",
    "# 原因是：[Errno 2] No such file or directory: 'test.txt'"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "一个`try`语句可能包含多个`except`子句，分别来处理不同的特定的异常。最多只有一个分支会被执行。\n",
    "\n",
    "【例子】\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "数值出错\n",
      "原因是：invalid literal for int() with base 10: 'abc'\n"
     ]
    }
   ],
   "source": [
    "try:\n",
    "    int(\"abc\")\n",
    "    s = 1 + '1'\n",
    "    f = open('test.txt')\n",
    "    print(f.read())\n",
    "    f.close()\n",
    "except OSError as error:\n",
    "    print('打开文件出错\\n原因是：' + str(error))\n",
    "except TypeError as error:\n",
    "    print('类型出错\\n原因是：' + str(error))\n",
    "except ValueError as error:\n",
    "    print('数值出错\\n原因是：' + str(error))\n",
    "\n",
    "# 数值出错\n",
    "# 原因是：invalid literal for int() with base 10: 'abc'"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "【例子】"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "查询错误\n"
     ]
    }
   ],
   "source": [
    "dict1 = {'a': 1, 'b': 2, 'v': 22}\n",
    "try:\n",
    "    x = dict1['y']\n",
    "except LookupError:\n",
    "    print('查询错误')\n",
    "except KeyError:\n",
    "    print('键错误')\n",
    "else:\n",
    "    print(x)\n",
    "\n",
    "# 查询错误"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "`try-except-else`语句尝试查询不在`dict`中的键值对，从而引发了异常。这一异常准确地说应属于`KeyError`，但由于`KeyError`是`LookupError`的子类，且将`LookupError`置于`KeyError`之前，因此程序优先执行该`except`代码块。所以，使用多个`except`代码块时，必须坚持对其规范排序，要从最具针对性的异常到最通用的异常。\n",
    "\n",
    "\n",
    "【例子】"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "键错误\n"
     ]
    }
   ],
   "source": [
    "dict1 = {'a': 1, 'b': 2, 'v': 22}\n",
    "try:\n",
    "    x = dict1['y']\n",
    "except KeyError:\n",
    "    print('键错误')\n",
    "except LookupError:\n",
    "    print('查询错误')\n",
    "else:\n",
    "    print(x)\n",
    "\n",
    "# 键错误"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "\n",
    "\n",
    "【例子】一个 `except` 子句可以同时处理多个异常，这些异常将被放在一个括号里成为一个元组。\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "出错了！\n",
      "原因是：unsupported operand type(s) for +: 'int' and 'str'\n"
     ]
    }
   ],
   "source": [
    "try:\n",
    "    s = 1 + '1'\n",
    "    int(\"abc\")\n",
    "    f = open('test.txt')\n",
    "    print(f.read())\n",
    "    f.close()\n",
    "except (OSError, TypeError, ValueError) as error:\n",
    "    print('出错了！\\n原因是：' + str(error))\n",
    "\n",
    "# 出错了！\n",
    "# 原因是：unsupported operand type(s) for +: 'int' and 'str'"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "\n",
    "\n",
    "---\n",
    "## 4. try - except - finally 语句\n",
    "try:\n",
    "    检测范围\n",
    "except Exception[as reason]:\n",
    "    出现异常后的处理代码\n",
    "finally:\n",
    "    无论如何都会被执行的代码\n",
    "\n",
    "不管`try`子句里面有没有发生异常，`finally`子句都会执行。\n",
    "\n",
    "\n",
    "\n",
    "【例子】如果一个异常在`try`子句里被抛出，而又没有任何的`except`把它截住，那么这个异常会在`finally`子句执行后被抛出。\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "result is 2.0\n",
      "executing finally clause\n",
      "division by zero!\n",
      "executing finally clause\n"
     ]
    }
   ],
   "source": [
    "def divide(x, y):\n",
    "    try:\n",
    "        result = x / y\n",
    "        print(\"result is\", result)\n",
    "    except ZeroDivisionError:\n",
    "        print(\"division by zero!\")\n",
    "    finally:\n",
    "        print(\"executing finally clause\")\n",
    "\n",
    "\n",
    "divide(2, 1)\n",
    "# result is 2.0\n",
    "# executing finally clause\n",
    "divide(2, 0)\n",
    "# division by zero!\n",
    "# executing finally clause\n",
    "divide(\"2\", \"1\")\n",
    "# executing finally clause\n",
    "# TypeError: unsupported operand type(s) for /: 'str' and 'str'"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "---\n",
    "## 5. try - except - else 语句\n",
    "\n",
    "如果在`try`子句执行时没有发生异常，Python将执行`else`语句后的语句。\n",
    "\n",
    "```python\n",
    "try:\n",
    "    检测范围\n",
    "except:\n",
    "    出现异常后的处理代码\n",
    "else:\n",
    "    如果没有异常执行这块代码\n",
    "```\n",
    "\n",
    "使用`except`而不带任何异常类型，这不是一个很好的方式，我们不能通过该程序识别出具体的异常信息，因为它捕获所有的异常。\n",
    "\n",
    "try:\n",
    "    检测范围\n",
    "except(Exception1[, Exception2[,...ExceptionN]]]):\n",
    "   发生以上多个异常中的一个，执行这块代码\n",
    "else:\n",
    "    如果没有异常执行这块代码\n",
    "    \n",
    "【例子】\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "内容写入文件成功\n"
     ]
    }
   ],
   "source": [
    "try:\n",
    "    fh = open(\"testfile.txt\", \"w\")\n",
    "    fh.write(\"这是一个测试文件，用于测试异常!!\")\n",
    "except IOError:\n",
    "    print(\"Error: 没有找到文件或读取文件失败\")\n",
    "else:\n",
    "    print(\"内容写入文件成功\")\n",
    "    fh.close()\n",
    "\n",
    "# 内容写入文件成功"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "注意：`else`语句的存在必须以`except`语句的存在为前提，在没有`except`语句的`try`语句中使用`else`语句，会引发语法错误。\n",
    "\n",
    "---\n",
    "## 6. raise语句\n",
    "\n",
    "Python 使用`raise`语句抛出一个指定的异常。\n",
    "\n",
    "\n",
    "【例子】"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "An exception flew by!\n"
     ]
    }
   ],
   "source": [
    "try:\n",
    "    raise NameError('HiThere')\n",
    "except NameError:\n",
    "    print('An exception flew by!')\n",
    "    \n",
    "# An exception flew by!"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "name": "python383jvsc74a57bd0157117749ab258efa5af82cd13573a2060d806fbca7ba2ef3ff71ebe3be5b465",
   "display_name": "Python 3.8.3 64-bit ('python': virtualenv)"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.3"
  },
  "tianchi_metadata": {
   "competitions": [],
   "datasets": [],
   "description": "",
   "notebookId": "154754",
   "source": "dsw"
  },
  "toc": {
   "base_numbering": 1,
   "nav_menu": {},
   "number_sections": false,
   "sideBar": true,
   "skip_h1_title": false,
   "title_cell": "Python入门(一)",
   "title_sidebar": "Python入门(一)",
   "toc_cell": false,
   "toc_position": {
    "height": "calc(100% - 180px)",
    "left": "10px",
    "top": "150px",
    "width": "320px"
   },
   "toc_section_display": true,
   "toc_window_display": true
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}